package cn.hl.hm.util.http;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * 客户端模拟测试
 *
 * @author xianghan
 *         2016年8月3日 下午3:12:14
 */
public class HttpUtils {
    // 统一记录日志类
    private static Logger Log = LoggerFactory.getLogger(HttpUtils.class);
    private static final String contentType = "application/json;charset=UTF-8";
    private static final String contentEncoding = "application/json";


    /**
     * post方式请求
     *
     * @param sslPostUrl
     * @param headParam
     * @param body
     * @return
     */
    public static Map<String, String> toHttpsPost(String sslPostUrl, List<NameValuePair> headParam,
                                                   List<NameValuePair> formParams, final Map<String, File> formFiles,
                                                   String body) {
        Map<String, String> map = new HashMap<String, String>();
        CloseableHttpClient httpclient = null;
        try {
            // 创建默认的httpClient实例.
            httpclient = new SSLClient();
            HttpPost httpPost = new HttpPost(sslPostUrl);
            StringEntity se = null;
            CloseableHttpResponse response = null;
            if (headParam != null) {
                for (NameValuePair NP : headParam) {
                    httpPost.addHeader(NP.getName(), NP.getValue());
                    System.out.println(NP.getName() + ":" + NP.getValue());
                }
            }
//            else {
//                httpPost.addHeader("Content-Type", contentType);
//            }
            if (body != null) {
                System.out.println(body.toString());
                se = new StringEntity(body, "UTF-8");
                se.setContentType("text/json;charset=UTF-8");
                se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, contentEncoding));
                httpPost.setEntity(se);
                Log.debug("executing request" + httpPost.getURI());
            }
            if (formParams != null || formFiles != null) {
                HttpEntity reqEntity = makeMultipartEntity(formParams, formFiles);
                httpPost.setEntity(reqEntity);

            }

            response = httpclient.execute(httpPost);
            map = responsePrint(response);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭连接,释放资源
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return map;
    }


    /**
     * http方式post方式请求
     *
     * @param httpPostUrl
     * @param headParam
     * @param body
     * @return
     */
    public static Map<String, String> toHttpPost(String httpPostUrl,
                                                 List<NameValuePair> headParam,
                                                 List<NameValuePair> formParams, final Map<String, File> formFiles,
                                                 String body) {
        Map<String, String> map = new HashMap<String, String>();
        CloseableHttpClient httpclient = null;
        try {
            // 创建默认的httpClient实例.
            httpclient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(httpPostUrl);
            StringEntity se = null;
            CloseableHttpResponse response = null;
            if (headParam != null) {
                for (NameValuePair NP : headParam) {
                    httpPost.addHeader(NP.getName(), NP.getValue());
                }
            }
//            else {
//                httpPost.addHeader("Content-Type", contentType);
//            }
            if (body != null) {
                se = new StringEntity(body, "UTF-8");
                se.setContentType("text/json;charset=UTF-8");
                se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, contentEncoding));
                httpPost.setEntity(se);
                Log.debug("executing request" + httpPost.getURI());
            }
            if (formParams != null || formFiles != null) {
                HttpEntity reqEntity = makeMultipartEntity(formParams, formFiles);
                httpPost.setEntity(reqEntity);

            }
            response = httpclient.execute(httpPost);
            map = responsePrint(response);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭连接,释放资源
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return map;
    }


    /**
     * put方式请求
     *
     * @param sslPostUrl
     * @param headParam
     * @param body
     * @return
     */
    public static Map<String, String> toHttpsPut(String sslPostUrl, List<NameValuePair> headParam, String body) {
        Map<String, String> map = new HashMap<String, String>();
        CloseableHttpClient httpclient = null;
        try {
            // 创建默认的httpClient实例.
            httpclient = new SSLClient();
            HttpPut httpPut = new HttpPut(sslPostUrl);
            StringEntity se = null;
            CloseableHttpResponse response = null;
            if (headParam != null) {
                for (NameValuePair NP : headParam) {
                    httpPut.addHeader(NP.getName(), NP.getValue());
                }
            } else {
                httpPut.addHeader("Content-Type", contentType);
            }
            if (body != null) {
                se = new StringEntity(body, "UTF-8");
                se.setContentType("text/json;charset=UTF-8");
                se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, contentEncoding));
                httpPut.setEntity(se);
                Log.debug("executing request" + httpPut.getURI());
            }
//            Log.debug("url:{},header:{}, body:{}", sslPostUrl, headParam, body);
            response = httpclient.execute(httpPut);
            map = responsePrint(response);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭连接,释放资源
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return map;
    }


    /**
     * get方式请求
     *
     * @param sslPostUrl
     * @param headParam
     * @param body
     * @return
     */
    public static Map<String, String> toHttpGet(String sslPostUrl, List<NameValuePair> headParam, String body) {
        Map<String, String> map = new HashMap<String, String>();
        CloseableHttpClient httpclient = null;
        try {
            // 创建默认的httpsClient实例.
            httpclient = HttpClients.createDefault();
            HttpGet httpGet = new HttpGet(sslPostUrl);
            StringEntity se = null;
            CloseableHttpResponse response = null;
            if (headParam != null) {
                for (NameValuePair NP : headParam) {
                    httpGet.addHeader(NP.getName(), NP.getValue());
                }
            } else {
                httpGet.addHeader("Content-Type", contentType);
            }
            if (body != null) {
                Log.debug("executing request" + httpGet.getURI());
            }
            response = httpclient.execute(httpGet);
            map = responsePrint(response);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭连接,释放资源
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return map;
    }

    private static Map<String, String> responsePrint(CloseableHttpResponse response) throws IOException {
        Map<String, String> map = new HashMap<String, String>();
        try {
            Log.debug("----------------------------------------");
            String status = response.getStatusLine().toString();
            Log.debug(status);
            status = status.substring(status.indexOf(" ", 0) + 1, status.lastIndexOf(" "));
            HttpEntity resEntity = response.getEntity();
            for (Header header : response.getAllHeaders()) {
                Log.debug("headerName:" + header.getName() + ",headerValue:" + header.getValue());
                map.put(header.getName(), header.getValue());
            }
            if (resEntity != null) {
                Log.debug("Response content length: " + resEntity.getContentLength());
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                int i = -1;
                while ((i = resEntity.getContent().read()) != -1) {
                    baos.write(i);
                }
                map.put("responseBody", new String(baos.toByteArray(), "UTF-8"));
                Log.debug("Response content: \n" + map.get("responseBody"));
            }
            Log.debug("----------------------------------------");
            EntityUtils.consume(resEntity);
        } catch (IllegalStateException ex) {
            Log.error("error", ex);
        } finally {
            response.close();
        }
        return map;
    }

    private static HttpEntity makeMultipartEntity(List<NameValuePair> params, final Map<String, File> files) {
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);    //如果有SocketTimeoutException等情况，可修改这个枚举
        //builder.setCharset(Charset.forName("UTF-8"));	//不要用这个，会导致服务端接收不到参数
        if (params != null && params.size() > 0) {
            for (NameValuePair p : params) {
                if(p!=null && p.getName()!=null){
                    builder.addTextBody(p.getName(), p.getValue()==null?"":p.getValue(), ContentType.TEXT_PLAIN.withCharset("UTF-8"));
                }else {
                    Log.info("Warning：Text may not be null，toString:"+p.toString());
                }
            }
        }
        if (files != null && files.size() > 0) {
            Set<Map.Entry<String, File>> entries = files.entrySet();
            for (Map.Entry<String, File> entry : entries) {
                builder.addPart(entry.getKey(), new FileBody(entry.getValue()));
            }
        }
        return builder.build();
    }

    public static void main(String[] args) {
        String postUrl = "http://localhost:8080/manage/driver/vehicle/update";
        List<NameValuePair> formParams = new ArrayList<>();
        NameValuePair nameValuePair = new BasicNameValuePair("driverId", "2932");
        formParams.add(nameValuePair);
        nameValuePair = new BasicNameValuePair("plateNumber", "京A123");
        formParams.add(nameValuePair);
        nameValuePair = new BasicNameValuePair("vehicleTpyeId", "48");
        formParams.add(nameValuePair);
        nameValuePair = new BasicNameValuePair("vehicleLengthId", "17");
        formParams.add(nameValuePair);
        nameValuePair = new BasicNameValuePair("transportLicense", "98767876549944");
        formParams.add(nameValuePair);
        nameValuePair = new BasicNameValuePair("drivingLicensePic", "");
        formParams.add(nameValuePair);
        nameValuePair = new BasicNameValuePair("drivingLicenseGuaPic", "");
        formParams.add(nameValuePair);
        Map<String, String> map = toHttpPost(postUrl, null,formParams,null, null);
//        for (String s : map.keySet()) {
//            System.out.print(s+","+map.get(s).toString());
//        }
    }

}

